ArrayList는 얕은 복사를 수행하니 같은 원본, 복사 두 ArrayList는 같은 객체들을 참조함을 확인할 수 있습니다.
Java로 보는 예시 - 직접 작성
그럼 직접 작성해보는 예시로는 깊은 복사를 수행해 봅시다.
우선 위에서 언급한 Cloneable을 구현해야 합니다.
보시면 override로 clone을 구현했습니다. 객체 내부의 리스트를 깊은 복사로 복사합니다.
main을 봅시다. 원본 객체를 복사한 객체를 두 개 생성하고 수정해주었습니다.
출력은 다음과 같습니다.
origin
James
Potter
Lin
NewTeam-1
Potter
Lin
NewTeam-2
James
Potter
Lin
만약 이 리스트가 DB에서 받아오는 것이라면, clone이 없이는 여러번 DB를 조회해야 합니다.
객체를 복사하는 것이 네트워크 접근이나 DB의 접근보다 훨씬 비용이 적은 것을 감안할 때, 한 번의 조회로 여러 수행을 할 수 있으니 큰 비용을 절약할 수 있었습니다.
프로토타입의 장점
객체를 생성하기 위한 별도의 객체 생성 클래스가 불필요 합니다.
팩토리 메소드 패턴과는 다르게 Creator가 필요 없음
객체의 각 부분을 조합해서 생성되는 형태에도 적용 가능합니다.
프로토타입의 단점
clone을 이용할 객체들의 자료형인 class에 clone() 메서드를 구현해야 합니다.
프로토타입 활용 용도
run-time에 새로운 제품을 추가하고 삭제할 수 있다.
프로토타입 패턴을 이용하면 사용자에게 원형으로 생성되는 인스턴스를 등록하는 것만으로도 시스템에 새로운 제품 클래스를 추가할 수 있게 됩니다. run-time에 새로운 프로토타입을 넣고 빼기가 쉽다는 점에서 다른 생성 패턴에 비해 유연성을 지니고 있습니다.
구조를 다양화 함으로써 새로운 객체를 명세할 수 있다.
많은 응용프로그램은 구성요소와 부분 구성요소의 복합을 통해 객체를 구축합니다. 예를 들어, 회로설계를 위한 편집기는 세부 회로를 모아서 큰 회로를 만듭니다. 이런 응용프로그램에서는 편의를 위한 복잡한 사용자 정의 구조를 사용자가 인스턴스화 하여 그 상황에 맞는 세부 회로를 계속 이용할 수 있도록 배려해 줄 때가 많습니다. 복합 회로 객체가 Clone() 연산을 구현함으로써 다른 구조를 갖는 회로의 기본 골격을 만듭니다.
서브클래스의 수를 줄일수 있다.
팩토리 메서드를 보면 Creator 클래스의 계통이 처리할 제품 관련 클래스의 계통과 병렬로 복합되는 것을 알 수 있습니다. 프로토타입 패턴에서는 팩토리 메서드에 새로원 객체를 만들어 달라고 요청하는 것이 아니라 원형을 복제하는 것으로, Creator 클래스에 따른 새로운 상속 계층이 필요 없습니다.
동적으로 클래스에 따라 응용프로그램을 설정할 수 있다.
몇몇 런타임 환경에서는 동적으로 클래스들을 응용프로그램으로 등록할 수 있도록 해 줍니다. 동적으로 로드 된 클래스의 인스턴스를 생성하고 싶은 응용프로그램은 정적으로 그 클래스의 생성자를 참조할 수 없습니다.
그 대신 런타임 환경이 그 클래스의 인스턴스를 자동으로 생성하고 원형 관리자에게 등록하면 응용프로그램은 이 원형 관리자에게서 필요한 클래스의 인스턴스를 얻을 수 있게 됩니다.